#pragma once
#include <SDL.h>
#include "math.h"
#include "GraphDrawer.h"
#include "../domain/List.h"
#include "SurfaceContainer.h"
#include "SurfaceContainerNode.h"
#include <iostream>

#define VIEWPORT_ATTACHED  0
#define VIEWPORT_TOP_LEFT  1
#define VIEWPORT_TOP_RIGHT  2
#define VIEWPORT_BOTTOM_LEFT  3
#define VIEWPORT_BOTTOM_RIGHT  4

typedef struct {
	int height;
	int width;
} T_Resolution;

class Viewport
{
private:
	SDL_Surface* windowScreen;
	SDL_Surface* fullScreen;
	SDL_Surface* originalScreen;
	T_Resolution viewportSize;
	T_Resolution screenResolution;
	int x_move;
	int y_move;
	int actual_x;
	int actual_y;
	float xProp;
	float yProp;
	List* surfacesToReRender;

	void repaintScreen(SDL_Surface* viewportScreen, SDL_Surface* fullScreen, int actual_x, int actual_y);
	SDL_Surface* resampleScreen(SDL_Surface* viewportScreen, int width_o, int height_o, int width_d, int height_d);
	void copyPixel(SDL_Surface* src_surface, SDL_Surface* dest_surface, Uint32 src_x, Uint32 src_y, Uint32 dest_x, Uint32 dest_y);
	int round (double value);
	SDL_Rect* createRectangle(int x, int y, int width, int height); 
	SDL_Surface* resampleFullScreen(SDL_Surface* fullScreen, T_Resolution viewportSize, T_Resolution screenResolution);
	void moveUp(int& y_move, int& actual_y);
	void moveDown(int& y_move, int& actual_y);
	void moveRight(int& x_move, int& actual_x);
	void moveLeft(int& x_move, int& actual_x);
	void drawSurfaceFittedToBorder(SurfaceContainer* surfaceContainer);
	void drawSurfaceAttachedToMap(SurfaceContainer* surfaceContainer);
public:

	Viewport(SDL_Surface* fullScreen, T_Resolution viewportSize , T_Resolution screenResolution);
	virtual ~Viewport(void);
	void draw();
	void refreshMovs();
	SDL_Surface* getWindowScreen();
	SDL_Surface* getFullScreen();
	void addSurfaceToRenderList(SDL_Surface* surface, std::string id, int x, int y, int positionType);
	void render();
	SDL_Surface* resampleSurfaceForWindow(SDL_Surface* surface);
	void updateSurfacePosition(std::string id, int newX, int newY);
	bool isVisible(SurfaceContainer* container);
	void setDirtySurface(std::string id);
	/*
	void drawSurfaceAt(SDL_Surface* surface, int x, int y);
	void Viewport::repaintScreenFromScratch();
	*/
};

